package com.beidouapp.security.mvc.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.beidouapp.domain.annotation.Right;
import com.beidouapp.security.model.ReturnDataInfo;
import com.beidouapp.utils.UIUtils;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;

public class AuthorityAnnotationInterceptor extends HandlerInterceptorAdapter {

	private final Logger logger = LoggerFactory.getLogger(AuthorityAnnotationInterceptor.class);

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		if (handler instanceof HandlerMethod) {
			HandlerMethod hm = (HandlerMethod) handler;

			Class<?> clazz = hm.getBeanType();
			Method m = hm.getMethod();
			try {
				if (clazz != null && m != null) {
					boolean isClzAnnotation = clazz.isAnnotationPresent(Right.class);
					boolean isMethondAnnotation = m.isAnnotationPresent(Right.class);
					Right authority = null;
					// 如果方法和类声明中同时存在这个注解，那么方法中的会覆盖类中的设定。
					if (isMethondAnnotation) {
						authority = m.getAnnotation(Right.class);
					} else if (isClzAnnotation) {
						authority = clazz.getAnnotation(Right.class);
					}
					if (authority != null) {
						String[] rightCode = authority.name();
						boolean check = false;
						if (rightCode != null && rightCode.length > 0) {
							List<String> belongRights = UIUtils.getSessionUser().getResourceCodes();
							if(belongRights != null && !belongRights.isEmpty()) {
								for (int i = 0; i < rightCode.length; i++) {
									for (String belongRight : belongRights) {
										if (rightCode[i].equals(belongRight)) {
											check = true;
											break;
										}
									}
								}
							}
						}
						if (!check) {
							flush2Response(request, response);
							return false;
						}
					}
					return true;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	protected void flush2Response(HttpServletRequest request, HttpServletResponse response)
			throws IOException, JSONException, ServletException {
		logger.info("session失效!");
		String url = request.getRequestURI();
		if (url.contains("/api/special/page/add")) {
			request.getRequestDispatcher("/api/special/login").forward(request, response);
		}
		else if (request.getContentType() != null && request.getContentType().indexOf("json") != -1) {
			ReturnDataInfo<String> info = new ReturnDataInfo<String>();
			info.setMessage("数据访问失败!");
			info.setStatusCode(503);
			JSONObject root = JSONObject.fromObject(info);
			response.setContentType("text/html; charset=utf-8");
			PrintWriter writer = response.getWriter();
			writer.print(root);
			writer.flush();
		} else {
			request.setAttribute("message", "您没有权限访问当前页面!");
			try {
				request.getRequestDispatcher("/api/toError").forward(request, response);
			} catch (ServletException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// response.sendRedirect(request.getContextPath() + "/api/toError");
		}
	}
}